package com.temdemo.utils.SnapPay;

import com.temdemo.utils.SnapPay.sign.SignHandler;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.gson.*;

import com.temdemo.utils.DateUtils;
import com.temdemo.utils.restful.CommonServiceException;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.util.*;

import static com.temdemo.utils.SnapPay.sign.SignHandler.GSON;


public class WXAppletApi {
    private static final Logger logger = LoggerFactory.getLogger(WXAppletApi.class);
    private static CloseableHttpClient httpClient = HttpClients.createDefault();

    /**
     * Merchant ID: 901800000116
     * Store No.: 80519419
     * AppID: 9f00cd9a873c511e
     * Signature Sign Key: 7e2083699dd510575faa1c72f9e35d43 (MD5)
     */
    private final static String HTTP_URL = "http://chenxi.gz2vip.idcfengye.com";
    private final static String HTTP_URL1 = "https://open.snappay.ca/api/gateway/";
    private final static String Char_Encoding = "UTF-8";
    private final static String Submit_Mode = "POST";
    private final static String Transfer_Mode = "HTTPS";
    private final static String Sign_Type = "MD5";
    private final static String Store_No = "80519419";

    //private final static String  Merchant_ID="901800000116";
    //private final static String  AppID="9f00cd9a873c511e";
    // private final static String  Signature_Sign_Key="7e2083699dd510575faa1c72f9e35d43";

    private final static String notify_url = HTTP_URL + "/Order/notify";
    private final static String return_url = HTTP_URL + "/pay/return";

    private final static String Merchant_ID = "902000043459";
    private final static String Signature_Sign_Key = "a39ac183caba5cb145216e928ae58257";
    private final static String AppID = "785c79a6a0b48cce";

    // 微信小程序支付
     public  synchronized static Map<String, Object> AppletPay(String subAppId,String orderNo,BigDecimal orderNum,String accountId,String description,
                                             JSONObject attach,JSONObject exParam) {
        TreeMap<String, Object> map = new TreeMap<>();
        map.put("app_id", AppID);
        map.put("notify_url", notify_url); // 	后台通知地址 商家后台接收开放服务网关支付异步通知回调地址 256
        map.put("merchant_no", Merchant_ID); // 商户号，在SnapPay入驻后生成的定常数字，用于标识商户身份  32
        map.put("format", "JSON");
        map.put("charset", "UTF-8");
        map.put("version", "1.0");
        map.put("timestamp", DateUtils.getUTCTime());
        map.put("method", "pay.minipay"); // 请求方法  此接口固定值为：pay.minipay   128
        map.put("payment_method", "WECHATPAY"); // 支付方式  目前只支付：WECHATPAY-微信支付 16
        map.put("trans_currency", "CAD"); //	符合ISO 4217标准的三位字母代码，如：CAD，USD标价币种必须与商户申请的结算币种一致，不填写则默认为CAD 8
        map.put("effective_minutes", 15); // 设置订单有效分钟数，超出有效时长不支付，订单将被关闭，不能再进行支付，默认为5分钟 取值范围：5分钟—60分钟

        map.put("out_order_no", orderNo); // 商户系统内部订单号，可以视为交易流水号，同一商户下订单号不能重复，即使交易没有成功 64
        //商户在微信公众平台申请移动应用或小程序得到的APPID（此APPID需要发邮件给SnapPay进行绑定）。
        // 当您在SnapPay绑定了多个APPID时，此为必选项，指定当前交易请求所使用的APPID
        map.put("sub_app_id",subAppId);//微信公众平台分配的App Id
        map.put("trans_amount", orderNum); //最大值：100000000.00
        map.put("pay_user_account_id", accountId ); // 用户子标识 微信Openid，下单前需要调用【网页授权获取用户信息】接口获取到用户的Openid。 64
        map.put("description",description ); //	订单描述 支付订单的简要描述。例：Ipad mini 16G 白色  128

        map.put("attach", attach); //商户附加信息 附加数据。该字段主要用于商户携带订单的自定义数据，且需要遵循JSON格式。在查询API和支付通知中原样返回 127
        map.put("extension_parameters", exParam); // 扩展参数 扩展输入参数，后续定义增加的参数存储于此JSON可变结构中

        JsonObject paramsJson = GSON.toJsonTree(map).getAsJsonObject();
        String sign = SignHandler.signWithMD5(paramsJson, Signature_Sign_Key);
        System.out.println("sign-签名：" + sign);
        map.put("sign", sign);
        map.put("sign_type", Sign_Type);

        Gson gson = new Gson();
        String gsonJSON = gson.toJson(map);
        System.out.println("入参json " + gsonJSON);

        Map<String, Object> resultMap = null;
        try {
            String mapJson = HttpPostUtils.doPost(HTTP_URL1, gsonJSON);
            resultMap = gson.fromJson(mapJson, Map.class);
            System.out.println("msg : " + resultMap.get("msg"));
            System.out.println("sign : " + resultMap.get("sign"));
            if (resultMap.get("code").equals("0") == true && resultMap.get("msg").equals("success") == true) {
                JsonObject resultJson = JsonParser.parseString(mapJson).getAsJsonObject();
                boolean isPass = SignHandler.verifySign(resultJson,Signature_Sign_Key);
                if(isPass==true){
                    //业务
                    for (Map.Entry<String, Object> entry : map.entrySet()) {
                        System.out.println(entry.getKey() + ": " + entry.getValue());
                    }
                }else{
                    logger.error("签名验证失败!");
                }
            }
        } catch (Exception e) {
            logger.error("调用异常 !");
            e.printStackTrace();
        }
        return null;
    }
    //微信小程序支付
/*    public static void main(String[] args) {
        System.out.println("执行调度方法");
        JSONObject json = new JSONObject();
        json.put("infor", "纯白色的ipad");
        JSONObject json1 = new JSONObject();
        json1.put("kz", "kz纯白色的ipad");
        AppletPay(AppID,"x12211",new BigDecimal("0.01"),"oSATF5IA137VIAmXd92RDylKc3k8","Ipad mini 16G 白色",json,json1);
    }*/


    // WEB网页支付
      public  synchronized static Map<String, Object> webPay(String paymentMethod,String browser_type,String orderNo,BigDecimal orderNum,String subject,String description,
                                             JSONObject attach,JSONObject exParam) {
        TreeMap<String, Object> map = new TreeMap<>();
        map.put("app_id", AppID);
        map.put("notify_url", notify_url); // 	后台通知地址 商家后台接收开放服务网关支付异步通知回调地址 256
        map.put("refer_url", return_url);
        map.put("merchant_no", Merchant_ID); // 商户号，在SnapPay入驻后生成的定常数字，用于标识商户身份  32
        map.put("format", "JSON");
        map.put("charset", "UTF-8");
        map.put("version", "1.0");
        //map.put("timestamp", DateUtils.getUTCTime());
        map.put("method", "pay.webpay"); // 请求方法  此接口固定值为：pay.webPay   128
        map.put("payment_method", paymentMethod); // 支付方式  目前支持的支付方式有：ALIPAY-支付宝 WECHATPAY-微信支付
        map.put("trans_currency", "CAD"); //	符合ISO 4217标准的三位字母代码，如：CAD，USD标价币种必须与商户申请的结算币种一致，不填写则默认为CAD 8
        map.put("effective_minutes", 15); // 设置订单有效分钟数，超出有效时长不支付，订单将被关闭，不能再进行支付，默认为5分钟 取值范围：5分钟—60分钟

        map.put("out_order_no", orderNo); // 商户系统内部订单号，可以视为交易流水号，同一商户下订单号不能重复，即使交易没有成功 64
        //商户在微信公众平台申请移动应用或小程序得到的APPID（此APPID需要发邮件给SnapPay进行绑定）。
        // 当您在SnapPay绑定了多个APPID时，此为必选项，指定当前交易请求所使用的APPID
        map.put("browser_type",browser_type);//PC：电脑网站支付，默认  WAP：手机网站支付  UNIONPAY仅支付PC网站支付
        map.put("trans_amount", orderNum); //最大值：100000000.00
        map.put("subject", subject ); // 商品的名称。例：Ipad 128
        map.put("description",description ); //	订单描述 支付订单的简要描述。例：Ipad mini 16G 白色  128

        map.put("attach", attach); //商户附加信息 附加数据。该字段主要用于商户携带订单的自定义数据，且需要遵循JSON格式。在查询API和支付通知中原样返回 127
        map.put("extension_parameters", exParam); // 扩展参数 扩展输入参数，后续定义增加的参数存储于此JSON可变结构中

        JsonObject paramsJson = GSON.toJsonTree(map).getAsJsonObject();
        String sign = SignHandler.signWithMD5(paramsJson, Signature_Sign_Key);
        System.out.println("sign-签名：" + sign);
        map.put("sign", sign);
        map.put("sign_type", Sign_Type);

        Gson gson = new Gson();
        String gsonJSON = gson.toJson(map);
        System.out.println("入参json " + gsonJSON);

        Map<String, Object> resultMap = null;
        try {
            String mapJson = HttpPostUtils.doPost(HTTP_URL1, gsonJSON);
            resultMap = gson.fromJson(mapJson, Map.class);
            System.out.println("msg : " + resultMap.get("msg"));
            System.out.println("sign : " + resultMap.get("sign"));
            if (resultMap.get("code").equals("0") == true && resultMap.get("msg").equals("success") == true) {
                JsonObject resultJson = JsonParser.parseString(mapJson).getAsJsonObject();
                boolean isPass = SignHandler.verifySign(resultJson,Signature_Sign_Key);
                if(isPass==true){
                    //业务
                    for (Map.Entry<String, Object> entry : resultMap.entrySet()) {
                        System.out.println(entry.getKey() + ": " + entry.getValue());
                    }
                }else{
                    logger.error("签名验证失败!");
                }
            }
        } catch (Exception e) {
            logger.error("调用异常 !");
            e.printStackTrace();
        }
        return null;
    }
    // WEB网页支付
    /*  public static void main(String[] args) {
        System.out.println("执行调度方法");
        JSONObject json = new JSONObject();
        json.put("infor", "纯白色的ipad");
        JSONObject json1 = new JSONObject();
        json1.put("kz", "kz纯白色的ipad");
        webPay("ALIPAY",AppID,"web012341",new BigDecimal("0.01"),"ipad","Ipad mini 16G 白色",json,json1);
       // System.out.println(DateUtils.getUTCTime());

    }*/

    // 扫码支付
    public synchronized static Map<String, Object> scodePay(String paymentMethod, String store_no, String orderNo, BigDecimal orderNum, String subject, String description,
                                               JSONObject attach, JSONObject exParam) {
        TreeMap<String, Object> map = new TreeMap<>();
        map.put("app_id", AppID);
        map.put("notify_url", notify_url); // 	后台通知地址 商家后台接收开放服务网关支付异步通知回调地址 256
        map.put("merchant_no", Merchant_ID); // 商户号，在SnapPay入驻后生成的定常数字，用于标识商户身份  32
        map.put("format", "JSON");
        map.put("charset", "UTF-8");
        map.put("version", "1.0");
        //map.put("timestamp", DateUtils.getUTCTime());
        map.put("method", "pay.qrcodepay"); // 请求方法  此接口固定值为：pay.minipay   128
        map.put("payment_method", paymentMethod); // ALIPAY-支付宝 WECHATPAY-微信支付 UNIONPAY_QR-银联云闪付
        map.put("trans_currency", "CAD"); //	符合ISO 4217标准的三位字母代码，如：CAD，USD标价币种必须与商户申请的结算币种一致，不填写则默认为CAD 8
        map.put("effective_minutes", 15); // 设置订单有效分钟数，超出有效时长不支付，订单将被关闭，不能再进行支付，默认为5分钟 取值范围：5分钟—60分钟

        map.put("out_order_no", orderNo); // 商户系统内部订单号，可以视为交易流水号，同一商户下订单号不能重复，即使交易没有成功 64
        //商户在微信公众平台申请移动应用或小程序得到的APPID（此APPID需要发邮件给SnapPay进行绑定）。
        // 当您在SnapPay绑定了多个APPID时，此为必选项，指定当前交易请求所使用的APPID
        map.put("store_no", store_no);//SnapPay分配的门店号 门店号用于区分同一个商户的不同门店。该号码由SnapPay在创建商户时分配。我们建议在请求中提供门店号以便于通过支付宝的风险控制。例如：“store_no”:“80000026”
        map.put("trans_amount", orderNum); //最大值：100000000.00
        map.put("subject", subject); // 商品的名称。例：Ipad 128
        map.put("description", description); //	订单描述 支付订单的简要描述。例：Ipad mini 16G 白色  128

        map.put("attach", attach); //商户附加信息 附加数据。该字段主要用于商户携带订单的自定义数据，且需要遵循JSON格式。在查询API和支付通知中原样返回 127
        map.put("extension_parameters", exParam); // 扩展参数 扩展输入参数，后续定义增加的参数存储于此JSON可变结构中

        JsonObject paramsJson = GSON.toJsonTree(map).getAsJsonObject();
        String sign = SignHandler.signWithMD5(paramsJson, Signature_Sign_Key);
        System.out.println("sign-签名：" + sign);
        map.put("sign", sign);
        map.put("sign_type", Sign_Type);

        Gson gson = new Gson();
        String gsonJSON = gson.toJson(map);
        System.out.println("入参json " + gsonJSON);

        Map<String, Object> resultMap = null;
        try {
            String mapJson = HttpPostUtils.doPost(HTTP_URL1, gsonJSON);
            resultMap = gson.fromJson(mapJson, Map.class);
            System.out.println("msg : " + resultMap.get("msg"));
            System.out.println("sign : " + resultMap.get("sign"));
            if (resultMap.get("code").equals("0") == true && resultMap.get("msg").equals("success") == true) {
                JsonObject resultJson = JsonParser.parseString(mapJson).getAsJsonObject();
                boolean isPass = SignHandler.verifySign(resultJson, Signature_Sign_Key);
                if (isPass == true) {
                    //业务
                    for (Map.Entry<String, Object> entry : resultMap.entrySet()) {
                        System.out.println(entry.getKey() + ": " + entry.getValue());
                    }
                } else {
                    logger.error("签名验证失败!");
                }
            }
        } catch (Exception e) {
            logger.error("调用异常 !");
            e.printStackTrace();
        }
        return null;
    }

    //扫码
   /* public static void main(String[] args) {
        System.out.println("执行调度方法");
        JSONObject json = new JSONObject();
        json.put("infor", "纯白色的ipad");
        JSONObject json1 = new JSONObject();
        json1.put("kz", "kz纯白色的ipad");
        scodePay("ALIPAY", null, "sc104", new BigDecimal("0.01"), "ipad", "Ipad mini 16G 白色", json, json1);
    }*/


    //H5 支付
   public synchronized static Map<String, Object> H5Pay(String paymentMethod,String userAccountId,String orderNo,BigDecimal orderNum,String description,
                                              JSONObject attach,JSONObject exParam) {
       TreeMap<String, Object> map = new TreeMap<>();
       map.put("app_id", AppID);
       map.put("notify_url", notify_url); // 	后台通知地址 商家后台接收开放服务网关支付异步通知回调地址 256
       map.put("return_url", return_url);
       map.put("merchant_no", Merchant_ID); // 商户号，在SnapPay入驻后生成的定常数字，用于标识商户身份  32
       map.put("format", "JSON");
       map.put("charset", "UTF-8");
       map.put("version", "1.0");
       //map.put("timestamp", DateUtils.getUTCTime());
       map.put("method", "pay.h5pay"); // 请求方法  此接口固定值为：pay.minipay   128
       map.put("payment_method", paymentMethod); // 目前支持的支付方式有：ALIPAY-支付宝  WECHATPAY-微信支付
       if(paymentMethod.equals("ALIPAY")){
           map.put("pay_channel_trade_type","JSAPI");
           map.put("pay_user_account_id",userAccountId);
       }
       map.put("trans_currency", "CAD"); //	符合ISO 4217标准的三位字母代码，如：CAD，USD标价币种必须与商户申请的结算币种一致，不填写则默认为CAD 8
       map.put("effective_minutes", 15); // 设置订单有效分钟数，超出有效时长不支付，订单将被关闭，不能再进行支付，默认为5分钟 取值范围：5分钟—60分钟

       map.put("out_order_no", orderNo); // 商户系统内部订单号，可以视为交易流水号，同一商户下订单号不能重复，即使交易没有成功 64
       //商户在微信公众平台申请移动应用或小程序得到的APPID（此APPID需要发邮件给SnapPay进行绑定）。
       // 当您在SnapPay绑定了多个APPID时，此为必选项，指定当前交易请求所使用的APPID
       map.put("trans_amount", orderNum); //最大值：100000000.00
       map.put("description",description ); //	订单描述 支付订单的简要描述。例：Ipad mini 16G 白色  128
       map.put("attach", attach); //商户附加信息 附加数据。该字段主要用于商户携带订单的自定义数据，且需要遵循JSON格式。在查询API和支付通知中原样返回 127
       map.put("extension_parameters", exParam); // 扩展参数 扩展输入参数，后续定义增加的参数存储于此JSON可变结构中
       JsonObject paramsJson = GSON.toJsonTree(map).getAsJsonObject();
       String sign = SignHandler.signWithMD5(paramsJson, Signature_Sign_Key);
       System.out.println("sign-签名：" + sign);
       map.put("sign", sign);
       map.put("sign_type", Sign_Type);

       Gson gson = new Gson();
       String gsonJSON = gson.toJson(map);
       System.out.println("入参json " + gsonJSON);

       Map<String, Object> resultMap = null;
       try {
           String mapJson = HttpPostUtils.doPost(HTTP_URL1, gsonJSON);
           resultMap = gson.fromJson(mapJson, Map.class);
           System.out.println("msg : " + resultMap.get("msg"));
           System.out.println("sign : " + resultMap.get("sign"));
           if (resultMap.get("code").equals("0") == true && resultMap.get("msg").equals("success") == true) {
               JsonObject resultJson = JsonParser.parseString(mapJson).getAsJsonObject();
               boolean isPass = SignHandler.verifySign(resultJson,Signature_Sign_Key);
               if(isPass==true){
                   //业务
                   for (Map.Entry<String, Object> entry : resultMap.entrySet()) {
                       System.out.println(entry.getKey() + ": " + entry.getValue());
                   }
               }else{
                   logger.error("签名验证失败!");
               }
           }
       } catch (Exception e) {
           logger.error("调用异常 !");
           e.printStackTrace();
       }
       return null;
   }

  /*  public static void main(String[] args) {
        System.out.println("执行调度方法");
        JSONObject json = new JSONObject();
        json.put("infor", "纯白色的ipad");
        JSONObject json1 = new JSONObject();
        json1.put("kz", "kz纯白色的ipad");
        H5Pay("WECHATPAY", null,"h5002", new BigDecimal("0.01"), "Ipad mini 16G 白色", json, json1);
    }*/


    //订单查询
    public  static Map<String, Object> queryOrder(String orderNo, String trans_no, JSONObject exParam) {
        TreeMap<String, Object> map = new TreeMap<>();
        map.put("app_id", AppID);
        //map.put("notify_url", notify_url); // 	后台通知地址 商家后台接收开放服务网关支付异步通知回调地址 256
        map.put("merchant_no", Merchant_ID); // 商户号，在SnapPay入驻后生成的定常数字，用于标识商户身份  32
        map.put("format", "JSON");
        map.put("charset", "UTF-8");
        map.put("version", "1.0");
        map.put("timestamp", DateUtils.getUTCTime());
        map.put("method", "pay.orderquery"); // 请求方法  此接口固定值为：pay.minipay   128

        //map.put("trans_no", trans_no); //开放服务网关平台交易号。out_order_no或trans_no两个参数需提供一个
        map.put("out_order_no", orderNo); // 商户系统内部订单号，同一商户下订单号不能重复。out_order_no或trans_no两个参数需提供一个

        map.put("extension_parameters", exParam); // 扩展参数 扩展输入参数，后续定义增加的参数存储于此JSON可变结构中
        JsonObject paramsJson = GSON.toJsonTree(map).getAsJsonObject();
        String sign = SignHandler.signWithMD5(paramsJson, Signature_Sign_Key);
        System.out.println("sign-签名：" + sign);
        map.put("sign", sign);
        map.put("sign_type", Sign_Type);

        Gson gson = new Gson();
        String gsonJSON = gson.toJson(map);
        System.out.println("入参json " + gsonJSON);

        Map<String, Object> resultMap = null;
        try {
            String mapJson = HttpPostUtils.doPost(HTTP_URL1, gsonJSON);
            resultMap = gson.fromJson(mapJson, Map.class);
            System.out.println("msg : " + resultMap.get("msg"));
            System.out.println("sign : " + resultMap.get("sign"));
            if (resultMap.get("code").equals("0") == true && resultMap.get("msg").equals("success") == true) {
                JsonObject resultJson = JsonParser.parseString(mapJson).getAsJsonObject();
                boolean isPass = SignHandler.verifySign(resultJson, Signature_Sign_Key);
                if (isPass == true) {
                    //业务
                    for (Map.Entry<String, Object> entry : resultMap.entrySet()) {
                        System.out.println(entry.getKey() + ": " + entry.getValue());
                    }
                } else {
                    logger.error("签名验证失败!");
                }
            }
        } catch (Exception e) {
            logger.error("调用异常 !");
            e.printStackTrace();
        }
        return null;
    }
    //订单查询
/*    public static void main(String[] args) {
        System.out.println("执行调度方法");
        JSONObject json = new JSONObject();
        json.put("infor", "纯白色的ipad");
        JSONObject json1 = new JSONObject();
        json1.put("kz", "kz纯白色的ipad");
        queryOrder("sc101",null,json1);
    }*/

    //回调
    public  synchronized  static Map<String, Object> notify(HttpServletRequest request, HttpServletResponse response) throws CommonServiceException {
        /**
         * String orderNo, String trans_no, String trans_status,String payment_method, String pay_user_account_id,
         *                                              String pay_user_account_name,String trans_currency,String exchange_rate,BigDecimal trans_amount,
         *                                              BigDecimal c_trans_fee, BigDecimal customer_paid_amount,BigDecimal discount_bmopc,BigDecimal discount_bpc ,
         *                                              String trans_end_time ,JSONObject attach
         */
       /* TreeMap<String, Object> map = new TreeMap<>();
        map.put("app_id", AppID);
        map.put("merchant_no", Merchant_ID); // 商户号，在SnapPay入驻后生成的定常数字，用于标识商户身份  32
        map.put("format", "JSON");
        map.put("charset", "UTF-8");
        map.put("version", "1.0");
        map.put("timestamp", DateUtils.getUTCTime());
        map.put("method", "pay.notify"); // 请求方法  此接口固定值为：pay.minipay   128

        map.put("trans_no", trans_no); //开放服务网关平台交易号
        map.put("out_order_no", orderNo); // 商户系统内部订单号，同一商户下订单号不能重复
        map.put("trans_status", trans_status );//SUCCESS - 交易成功
        map.put("payment_method", payment_method);//目前支持的支付方式有：ALIPAY 支付宝 WECHATPAY 微信支付 UNIONPAY 银联
        *//**
         * 支付宝返回支付用户的ID,例如：2088101117955611
         * 微信返回商户appid下用户唯一标识，例如：wx37150978513678
         * 银行卡交易返回加脱敏的卡号信息，例如：6226***1982
         *//*
        map.put("pay_user_account_id", pay_user_account_id);
        *//**
         * 159****5620或zhangsan@sina.com 注：支付宝支付返回账号登录名，微信支付时返回为空
         *//*
        map.put("pay_user_account_name", pay_user_account_name);
        map.put("trans_currency", trans_currency);
        map.put("exchange_rate", exchange_rate);
        map.put("trans_amount", trans_amount); //交易总金额
        map.put("c_trans_fee", c_trans_fee);
        map.put("customer_paid_amount", customer_paid_amount);//交易过程中从顾客资金账户中实际扣减的金额
        map.put("discount_bmopc", discount_bmopc);
        map.put("discount_bpc", discount_bpc);
        map.put("trans_end_time", trans_end_time);//交易成功时间
        map.put("attach", attach); // 扩展参数 扩展输入参数，后续定义增加的参数存储于此JSON可变结构中
        JsonObject paramsJson = GSON.toJsonTree(map).getAsJsonObject();
        String sign = SignHandler.signWithMD5(paramsJson, Signature_Sign_Key);
        System.out.println("sign-签名：" + sign);
        map.put("sign", sign);
        map.put("sign_type", Sign_Type);


        String gsonJSON = gson.toJson(map);
        System.out.println("入参json " + gsonJSON);*/

        Map<String, Object> resultMap = null;
        try {
            Gson gson = new Gson();
            InputStream inputStream = request.getInputStream();
            ByteArrayOutputStream result = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int length;
            while ((length = inputStream.read(buffer)) != -1) {
                result.write(buffer, 0, length);
            }
            String mapJson = result.toString(StandardCharsets.UTF_8.name());
            resultMap = gson.fromJson(mapJson, Map.class);
            System.out.println("sign : " + resultMap.get("sign"));
            JsonObject resultJson = JsonParser.parseString(mapJson).getAsJsonObject();
            boolean isPass = SignHandler.verifySign(resultJson, Signature_Sign_Key);
            if (isPass == true) {
                //业务
                for (Map.Entry<String, Object> entry : resultMap.entrySet()) {
                    System.out.println(entry.getKey() + ": " + entry.getValue());
                }
                Map<String, Object> resultmap = new TreeMap<>();
                resultmap.put("code", "0");
                response.setContentType("application/json;charset=utf-8");
                OutputStream out = response.getOutputStream();
                out.write(JSON.toJSONString(resultmap).getBytes("UTF-8"));
                out.flush();
            } else {
                logger.error("签名验证失败!");
            }

        } catch (Exception e) {
            logger.error("调用异常 !");
            e.printStackTrace();
        }
        return null;
    }



    //订单撤销
    public synchronized static Map<String, Object> orderCancel(String orderNo, JSONObject exParam) {
        TreeMap<String, Object> map = new TreeMap<>();
        map.put("app_id", AppID);
        //map.put("notify_url", notify_url); // 	后台通知地址 商家后台接收开放服务网关支付异步通知回调地址 256
        map.put("merchant_no", Merchant_ID); // 商户号，在SnapPay入驻后生成的定常数字，用于标识商户身份  32
        map.put("format", "JSON");
        map.put("charset", "UTF-8");
        map.put("version", "1.0");
        map.put("timestamp", DateUtils.getUTCTime());
        map.put("method", "pay.ordercancel"); // 请求方法  此接口固定值为：pay.minipay   128
        map.put("out_order_no", orderNo); // 商户系统内部订单号，同一商户下订单号不能重复。out_order_no或trans_no两个参数需提供一个
        map.put("extension_parameters", exParam); // 扩展参数 扩展输入参数，后续定义增加的参数存储于此JSON可变结构中

        JsonObject paramsJson = GSON.toJsonTree(map).getAsJsonObject();
        String sign = SignHandler.signWithMD5(paramsJson, Signature_Sign_Key);
        System.out.println("sign-签名：" + sign);
        map.put("sign", sign);
        map.put("sign_type", Sign_Type);

        Gson gson = new Gson();
        String gsonJSON = gson.toJson(map);
        System.out.println("入参json " + gsonJSON);

        Map<String, Object> resultMap = null;
        try {
            String mapJson = HttpPostUtils.doPost(HTTP_URL1, gsonJSON);
            resultMap = gson.fromJson(mapJson, Map.class);
            System.out.println("msg : " + resultMap.get("msg"));
            System.out.println("sign : " + resultMap.get("sign"));
            if (resultMap.get("code").equals("0") == true && resultMap.get("msg").equals("success") == true) {
                JsonObject resultJson = JsonParser.parseString(mapJson).getAsJsonObject();
                boolean isPass = SignHandler.verifySign(resultJson, Signature_Sign_Key);
                if (isPass == true) {
                    //业务
                    for (Map.Entry<String, Object> entry : resultMap.entrySet()) {
                        System.out.println(entry.getKey() + ": " + entry.getValue());
                    }
                } else {
                    logger.error("签名验证失败!");
                }
            }
        } catch (Exception e) {
            logger.error("调用异常 !");
            e.printStackTrace();
        }
        return null;
    }
    //订单撤销
    public static void main(String[] args) {
        System.out.println("执行调度方法");
        JSONObject json = new JSONObject();
        json.put("infor", "纯白色的ipad");
        orderCancel("sc104",json);
    }


    //订单退款
    public synchronized static Map<String, Object> orderRefund(String orderNo, String out_refund_no,
                                                  BigDecimal refund_amount, String refund_desc, JSONObject exParam) {
        TreeMap<String, Object> map = new TreeMap<>();
        map.put("app_id", AppID);
        map.put("merchant_no", Merchant_ID); // 商户号，在SnapPay入驻后生成的定常数字，用于标识商户身份  32
        map.put("format", "JSON");
        map.put("charset", "UTF-8");
        map.put("version", "1.0");
        map.put("timestamp", DateUtils.getUTCTime());
        map.put("method", "pay.orderrefund"); // 请求方法  此接口固定值为：pay.minipay   128
        map.put("out_order_no", orderNo); // 商户系统内部订单号，同一商户下订单号不能重复。out_order_no或trans_no两个参数需提供一个
        map.put("out_refund_no", out_refund_no);//商户系统内部的退款单号，商户系统内部唯一，同一退款单号多次请求只退一笔。当前退款交易的订单号
        map.put("refund_amount", refund_amount); //本次申请退款金额
        map.put("refund_desc", refund_desc); //本次申请退款金额
        map.put("extension_parameters", exParam); // 扩展参数 扩展输入参数，后续定义增加的参数存储于此JSON可变结构中

        JsonObject paramsJson = GSON.toJsonTree(map).getAsJsonObject();
        String sign = SignHandler.signWithMD5(paramsJson, Signature_Sign_Key);
        System.out.println("sign-签名：" + sign);
        map.put("sign", sign);
        map.put("sign_type", Sign_Type);

        Gson gson = new Gson();
        String gsonJSON = gson.toJson(map);
        System.out.println("入参json " + gsonJSON);

        Map<String, Object> resultMap = null;
        try {
            String mapJson = HttpPostUtils.doPost(HTTP_URL1, gsonJSON);
            resultMap = gson.fromJson(mapJson, Map.class);
            System.out.println("msg : " + resultMap.get("msg"));
            System.out.println("sign : " + resultMap.get("sign"));
            if (resultMap.get("code").equals("0") == true && resultMap.get("msg").equals("success") == true) {
                JsonObject resultJson = JsonParser.parseString(mapJson).getAsJsonObject();
                boolean isPass = SignHandler.verifySign(resultJson, Signature_Sign_Key);
                if (isPass == true) {
                    //业务
                    for (Map.Entry<String, Object> entry : resultMap.entrySet()) {
                        System.out.println(entry.getKey() + ": " + entry.getValue());
                    }
                } else {
                    logger.error("签名验证失败!");
                }
            }
        } catch (Exception e) {
            logger.error("调用异常 !");
            e.printStackTrace();
        }
        return null;
    }

   /* public static void main(String[] args) {
        System.out.println("执行调度方法");
        JSONObject json = new JSONObject();
        json.put("infor", "纯白色的ipad");
        orderRefund("sc101", "rf001", new BigDecimal("0.01"), "测试退款", json);
    }*/
}
